<template>
  <a-tabs v-model="activeKey"
          hideAdd
          :type="$store.getTheme('tabType')"
          @change="onTabChange"
          @edit="onEdit">
    <a-tab-pane v-for="page in pages"
                :key="getTabKey(page)"
                :closable="pages.length > 1">
      <a-dropdown slot="tab"
                  :trigger="['contextmenu']">
        <span style="display:inline-block; height: 100%">
          {{ getTabTitle(page) }}
        </span>
        <a-menu slot="overlay">
          <a-menu-item key="refresh"
                       @click="refresh(page)">
            <a-icon type="reload" />
            刷新
          </a-menu-item>
          <a-menu-item @click="onEdit(getTabKey(page), 'remove')"
                       v-if="pages.length > 1">
            <a-icon type="close" />
            关闭
          </a-menu-item>
          <a-menu-item @click="closeOther(page)"
                       v-if="pages.length > 1">
            <a-icon type="close-circle" />
            关闭其他
          </a-menu-item>
          <a-menu-item @click="closeRight(page)"
                       v-if="pages.length > 1">
            <a-icon type="arrow-right" />
            关闭右侧
          </a-menu-item>
          <a-menu-item @click="closeLeft(page)"
                       v-if="pages.length > 1">
            <a-icon type="arrow-left" />
            关闭左侧
          </a-menu-item>
        </a-menu>
      </a-dropdown>
    </a-tab-pane>
  </a-tabs>
</template>

<script>
/**
 * 多标签组件基类
 */
export default {
  model: {
    prop: 'pages',
    event: 'change'
  },
  props: {
    activeTab: {
      type: String,
      default: ''
    },
    pages: {
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      activeKey: ''
    }
  },
  created () {
    // 重写 window.history.go
    window.history.go = (n) => {
      this.back(n)
    }
    this.handleRouteChange()
  },
  watch: {
    '$route' () {
      this.handleRouteChange()
    },
    activeTab: {
      immediate: true,
      handler (n) {
        this.activeKey = n
      }
    }
  },
  methods: {
    handleRouteChange () { },
    getTabTitle (page) { },
    getTabKey (page) { },
    back () { },
    onTabChange (key) {
      const page = this.pages.find(p => this.getTabKey(p) == key)
      this.loadRoute(page)
      this.$emit('tabChange', key, page)
    },
    onEdit (key, action) {
      this[action](key)
    },
    remove (key) {
      const pages = [...this.pages]
      this.pages.length = 0
      pages.map(p => {
        this.getTabKey(p) != key && this.pages.push(p)
      })
      let current = this.pages.find(p => this.getTabKey(p) == this.getTabKey(this.$route))
      !current && (current = this.pages[this.pages.length - 1])
      this.loadRoute(current)
      this.$emit('tabChange', this.getTabKey(current), current)
      // 更新路由保持
      this.$store.updateKeepAlive(this.pages)
    },
    refresh (page) {
      this.activeKey = this.getTabKey(page)
      const index = this.pages.indexOf(page)
      if (page.meta.target) {
        this.pages.splice(index, 1)
        this.$nextTick(() => { this.pages.splice(index, 0, page) })
      } else {
        this.$router.reload()
      }
      this.$emit('tabChange', this.activeKey, page)
    },
    closeOther (page) {
      this.pages.length = 0
      this.pages.push(page)
      this.loadRoute(page)
      this.$emit('tabChange', this.getTabKey(page), page)
    },
    closeRight (page) {
      this.pages.length = this.pages.indexOf(page) + 1
      let current = this.pages.find(p => this.getTabKey(p) == this.getTabKey(this.$router))
      !current && (current = this.pages[this.pages.length - 1])
      this.$emit('tabChange', this.getTabKey(current), current)
    },
    closeLeft (page) {
      this.pages.splice(0, this.pages.indexOf(page))
      let current = this.pages.find(p => this.getTabKey(p) == this.getTabKey(this.$router))
      !current && (current = this.pages[this.pages.length - 1])
      this.$emit('tabChange', this.getTabKey(current), current)
    },
    loadRoute (page) {
      if (page?.meta?.target) {
        return
      }
      if (page.meta.stack) {
        this.$router.push(page.meta.stack[page.meta.stack.length - 1])
      } else {
        this.$router.push(page)
      }
    },
    getParent (page) {
      const p = page || this.$route
      const matched = [...(p.meta.matched || p.matched)]
      let matchedParent = matched.pop()
      while (matchedParent?.meta?.type == '3') {
        matchedParent = matched.pop()
      }
      return matchedParent
    }
  }
}
</script>